<template>
  <el-card>
    <div v-for="parent in list" :key="parent.id">
      <el-checkbox v-model="parent.checkAll" :indeterminate="parent.isIndeterminate" @change="allChange(parent)">{{
        parent.name }}</el-checkbox>
      <el-checkbox-group v-model="parent.checkeds" @change="childChange(parent)">
        <el-row>
          <el-col :span="8" v-for="child in parent.children" :key="child.id">
            <el-checkbox :label="child.id">{{
              child.name
            }}</el-checkbox>
          </el-col>
        </el-row>

      </el-checkbox-group>
    </div>
    <div>
      <el-button type="primary" @click="save">保存</el-button>
    </div>
  </el-card>
</template>
<script setup lang='ts'>
import { getAllResourceApi, getRoleResourceApi, getAllResourceTypeApi } from '@/api';
import { useRoute } from 'vue-router';
import { ref } from 'vue'
const route = useRoute();
// if(route.query.id) {}
// let categories = ref<IResourceCategoryModel[]>([]);
// let resources = ref<IResourceModel[]>([])
// 要把上面的两个数组组成父子关系，使用双层v-for渲染到页面上 ，所以上面的代码可以不要了
// 请求都是异步的，实现父子关系的时候，是否需要两个数据都回来？是！！！
// 如何保证两个数据都回来？ Promise.all()
// let roleResources = ref<IResourceModel[]>([])

// 构建一个满足父子关系的类型
type IList = IResourceCategoryModel & { children: IResourceModel[], checkAll: boolean, isIndeterminate: boolean, checkeds: number[] }
let list = ref<IList[]>([])

// 所有的资源数据，都放到这里请求
Promise.all([getAllResourceTypeApi(), getAllResourceApi(), getRoleResourceApi(route.params.id as any as number)]).then(res => {
  const [categoryRes, resourceRes, roleResourcesRes] = res;
  if (categoryRes.code === 200 && resourceRes.code === 200 && roleResourcesRes.code === 200) {
    // 构建父子关系
    // 先遍历 1级
    categoryRes.data.forEach(parent => {
      let obj: IList = {
        ...parent,
        checkAll: false,
        isIndeterminate: false,
        checkeds: [],
        children: []
      };
      list.value.push(obj)
      resourceRes.data.forEach(child => {
        if (child.categoryId === parent.id) {
          obj.children.push(child)
        }
      })
    })

    // 把1级资源的 checkeds 数组，根据角色拥有的 资源，设置一下
    roleResourcesRes.data.forEach(item => {
      list.value.forEach(l => {
        if (l.id === item.categoryId) {
          // 找到了 角色拥有的 资源的 父级
          l.checkeds.push(item.id)
        }
        // 这个判断可以减少 -- 自己处理
        l.checkAll = l.checkeds.length === l.children.length;
        l.isIndeterminate = l.checkeds.length > 0 && l.checkeds.length < l.children.length;
      })

    })
  }
})


// 全选的事件
const allChange = (item: IList) => {
  // 点的谁，就要把子级的状态变成和我是一样的
  let ckAll = item.checkAll;
  if (ckAll) {
    // 把所有的子级全选
    item.checkeds = item.children.map(c => c.id);
  } else {
    // 全不选
    item.checkeds = [];
  }
}

// 点击子级
const childChange = (item: IList) => {
  // 子级在点击的时候，还可能会全选
  item.checkAll = item.checkeds.length == item.children.length
  // 判断所有的子级是否勾选大于0个，小于长度个
  item.isIndeterminate = item.checkeds.length > 0 && item.checkeds.length < item.children.length;
}

const save = () => {
  // 发请求
  // 请求要的参数： roleId-  当前的角色的id - route.query.id
  //               resourceIds - 勾选的资源的id
  // let ids: number[] = []
  // list.value.forEach(p => {
  //     p.checkeds.forEach(c => {
  //         ids.push(c)
  //     })
  // })
  // console.log(ids)

  let ids = list.value.reduce<number[]>((prev, current) => {
    prev.push(...current.checkeds)
    return prev;
  }, [])
  console.log(ids)
}
</script>
<style lang="less" scoped></style>